package com.mycat.dfs.server.impl;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;

import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerGroup;
import org.csource.fastdfs.TrackerServer;

import com.mycat.dfs.server.FastDFSService;

/**
 * 文件服务
 *
 * @author Roger
 */
public class FastDFSUtils implements FastDFSService {
	/**
	 * 配置文件地址
	 */
	private String fdfsConfigPath;
	/**
	 * 存储客户端对象
	 */
	private StorageClient storageClient;

	private int connect_timeout;
	private String charset;
	private int network_timeout;
	private String secret_key;
	private int tracker_http_port;
	private boolean anti_steal_token;
	private String tracker_server_ip;
	private int tracker_server_port;

	public void init() throws FileNotFoundException, IOException, MyException {
		ClientGlobal.setG_connect_timeout(connect_timeout);
		ClientGlobal.setG_charset(charset);
		ClientGlobal.setG_network_timeout(network_timeout);
		ClientGlobal.setG_secret_key(secret_key);
		
		InetAddress addr = InetAddress.getByName(tracker_server_ip);
		InetSocketAddress tracker_servers = new InetSocketAddress(addr, tracker_server_port);
		InetSocketAddress[] tracker_servers_array = new InetSocketAddress[1];
		tracker_servers_array[0] = tracker_servers;

		ClientGlobal.setG_tracker_group(new TrackerGroup(tracker_servers_array));
		ClientGlobal.setG_tracker_http_port(tracker_http_port);
		ClientGlobal.setG_anti_steal_token(anti_steal_token);

		TrackerClient tracker = new TrackerClient();
		TrackerServer trackerServer = null;
		trackerServer = tracker.getConnection();
		StorageServer storageServer = null;
		storageClient = new StorageClient(trackerServer, storageServer);
	}

	@Override
	public String uploadFile(String file) throws Exception {
		return uploadFile(file, null);
	}

	@Override
	public String uploadFile(String file, NameValuePair[] metaList)  throws Exception{
		try {
			String fileIds[] = storageClient.upload_file(file,
					file.substring(file.lastIndexOf('.') + 1, file.length()), metaList);
			if (fileIds != null) {
				return fileIds[0] + "/" + fileIds[1];
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		throw new Exception("上传文件出现异常");
	}

	@Override
	public byte[] downloadFile(String file) throws Exception {
		String groupName = file.substring(0, file.indexOf('/'));
		String filename = file.substring(file.indexOf('/') + 1, file.length());
		try {
			return storageClient.download_file(groupName, filename);
		} catch (IOException | MyException e) {
			e.printStackTrace();
		}
		throw new Exception("上传文件出现异常");
	}

	@Override
	public FileInfo getFileInfo(String file) throws Exception {
		String groupName = file.substring(0, file.indexOf('/'));
		String filename = file.substring(file.indexOf('/') + 1, file.length());
		try {
			return storageClient.get_file_info(groupName, filename);
		} catch (IOException | MyException e) {
			e.printStackTrace();
		}
		throw new Exception("获取文件出现异常");
	}

	@Override
	public NameValuePair[] getFileMeteInfo(String file) throws Exception {
		String groupName = file.substring(0, file.indexOf('/'));
		String filename = file.substring(file.indexOf('/') + 1, file.length());
		try {
			return storageClient.get_metadata(groupName, filename);
		} catch (IOException | MyException e) {
			e.printStackTrace();
		}
		throw new Exception("获取文件出现异常");
	}

	@Override
	public int deleteFile(String file) throws Exception {
		String groupName = file.substring(0, file.indexOf('/'));
		String filename = file.substring(file.indexOf('/') + 1, file.length());
		try {
			return storageClient.delete_file(groupName, filename);
		} catch (IOException | MyException e) {
			e.printStackTrace();
		}
		return -1;
	}

	public String getFdfsConfigPath() {
		return fdfsConfigPath;
	}

	public void setFdfsConfigPath(String fdfsConfigPath) {
		this.fdfsConfigPath = fdfsConfigPath;
	}

	@Override
	public String uploadFile(InputStream is, String fileExtName, NameValuePair[] metaList) throws Exception {
		try {
			String[] fileIds = storageClient.upload_file(input2byte(is), fileExtName, metaList);
			if (fileIds != null) {
				return fileIds[0] + "/" + fileIds[1];
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (MyException e) {
			e.printStackTrace();
		}
		throw new Exception("上传文件出现异常");
	}

	@Override
	public String uploadFile(InputStream is, String fileExtName) throws Exception {
		return uploadFile(is, fileExtName, null);
	}

	private static final byte[] input2byte(InputStream inStream) throws IOException {
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
		byte[] buff = new byte[100];
		int rc = 0;
		while ((rc = inStream.read(buff, 0, 100)) > 0) {
			swapStream.write(buff, 0, rc);
		}
		byte[] in2b = swapStream.toByteArray();
		return in2b;
	}

	@Override
	public String uploadFileByByte(byte[] b, String fileExtName) throws Exception {
		try {
			String[] fileIds = storageClient.upload_file(b, fileExtName, null);
			if (fileIds != null) {
				return fileIds[0] + "/" + fileIds[1];
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (MyException e) {
			e.printStackTrace();
		}
		throw new Exception("上传文件出现异常");
	}

	public StorageClient getStorageClient() {
		return storageClient;
	}

	public void setStorageClient(StorageClient storageClient) {
		this.storageClient = storageClient;
	}

	public int getConnect_timeout() {
		return connect_timeout;
	}

	public void setConnect_timeout(int connect_timeout) {
		this.connect_timeout = connect_timeout;
	}

	public String getCharset() {
		return charset;
	}

	public void setCharset(String charset) {
		this.charset = charset;
	}

	public int getNetwork_timeout() {
		return network_timeout;
	}

	public void setNetwork_timeout(int network_timeout) {
		this.network_timeout = network_timeout;
	}

	public String getSecret_key() {
		return secret_key;
	}

	public void setSecret_key(String secret_key) {
		this.secret_key = secret_key;
	}

	public int getTracker_http_port() {
		return tracker_http_port;
	}

	public void setTracker_http_port(int tracker_http_port) {
		this.tracker_http_port = tracker_http_port;
	}

	public boolean isAnti_steal_token() {
		return anti_steal_token;
	}

	public void setAnti_steal_token(boolean anti_steal_token) {
		this.anti_steal_token = anti_steal_token;
	}

	public String getTracker_server_ip() {
		return tracker_server_ip;
	}

	public void setTracker_server_ip(String tracker_server_ip) {
		this.tracker_server_ip = tracker_server_ip;
	}

	public int getTracker_server_port() {
		return tracker_server_port;
	}

	public void setTracker_server_port(int tracker_server_port) {
		this.tracker_server_port = tracker_server_port;
	}
}
